package com.ys.service.storage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.dto.EditDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.storage.*;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.storage.TccStockSourceEnum;
import com.ys.mapper.storage.StorageMapper;
import com.ys.mapper.storage.TccLocationTransferItemMapper;
import com.ys.mapper.storage.TccLocationTransferMapper;
import com.ys.service.flow.YspTaskService;
import com.ys.service.storage.TccLocationTransferService;
import com.ys.service.storage.TccStockControlService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Author: fxz
 * @CreateTime: 2024-11-25
 * @Description: 货位转移单
 * @Version: 1.0
 */
@Service("tccLocationTransferService")
public class TccLocationTransferServiceImpl implements TccLocationTransferService {

    @Autowired
    private TccLocationTransferMapper tccLocationTransferMapper;

    @Autowired
    private TccLocationTransferItemMapper tccLocationTransferItemMapper;

    @Autowired
    private YspTaskService yspTaskService;

    @Autowired
    private StorageMapper storageMapper;

    @Autowired
    private TccStockControlService tccStockControlService;

    /**
     * 新增
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R add(String bid, String remark, String detailArr ) throws Exception {
        if (bid == null){
            return R.error("单号不允许为空!");
        }
        TccLocationTransfer tccLocationTransfer = new TccLocationTransfer();
        tccLocationTransfer.setBid(bid);
        tccLocationTransfer.setRemark(remark);

        // 验证是否有详情数据
        JSONArray detailJA = JSON.parseArray(detailArr);
        if (detailJA == null || detailJA.size() == 0) {
            return R.error("详情数据不能为空");
        }

        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            if (detailJO.getInteger("transferNum") == null){
                return R.error("转移数量不能为空!");
            }else if (detailJO.getInteger("transferNum") == 0){
                return R.error("转移数量不能0!");
            }
            if (detailJO.getString("vhwYr") == null){
                return R.error("移入货位不能为空!");
            }
        }

        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();

        tccLocationTransfer.setStatus(1);
        tccLocationTransfer.setCreateChangeId(tsUserChange.getId());
        tccLocationTransfer.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);
        tccLocationTransferMapper.insert(tccLocationTransfer);


        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TccLocationTransferItem tccLocationTransferItem = JSON.parseObject(JSON.toJSONString(detailJO), TccLocationTransferItem.class);
            tccLocationTransferItem.setPbid(bid);
            tccLocationTransfer.setStatus(1);
            tccLocationTransferItemMapper.insert(tccLocationTransferItem);
        }
        YsMenu ysMenu = new YsMenu().setId(MenuId.TCC_LocationTransfer).queryFirst();
        if (ysMenu.getFlowModelId().longValue() != 0L) {
            YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
            String codeModel = yspModel.getCode();
            String createUserId = ShiroUtils.getUserId();
            yspTaskService.init(codeModel, bid, createUserId);
        }
        return R.ok(AddDto.gotoEdit("/web/storage/tccLocationTransfer/toEdit?bid=" + bid));
    }


    /**
     * 修改
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R edit(String bid, String remark, String detailArr) throws Exception {
        if (bid == null){
            return R.error("单号不允许为空!");
        }
        TccLocationTransfer tccLocationTransfer = new TccLocationTransfer().setBid(bid).queryFirst();
        if (tccLocationTransfer == null){
            return R.error("货位转移单不存在!");
        }
        tccLocationTransfer.setRemark(remark);

        // 验证是否有详情数据
        JSONArray detailJA = JSON.parseArray(detailArr);
        if (detailJA == null || detailJA.size() == 0) {
            return R.error("详情数据不能为空");
        }

        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            if (detailJO.getInteger("transferNum") == null){
                return R.error("转移数量不能为空!");
            }else if (detailJO.getInteger("transferNum") == 0){
                return R.error("转移数量不能0!");
            }
            if (detailJO.getString("vhwYr") == null){
                return R.error("移入货位不能为空!");
            }
        }

        tccLocationTransferMapper.update(tccLocationTransfer);

        storageMapper.deleteTccLocationTransferItemByPbid(bid);

        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TccLocationTransferItem tccLocationTransferItem = JSON.parseObject(JSON.toJSONString(detailJO), TccLocationTransferItem.class);
            tccLocationTransferItem.setPbid(bid);
            tccLocationTransfer.setStatus(1);
            tccLocationTransferItemMapper.insert(tccLocationTransferItem);
        }

        return R.ok(AddDto.gotoEdit("/web/storage/tccLocationTransfer/toEdit?bid=" + bid));
    }

    /**
     * 删除
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R deleteTrue(Long id) throws Exception {
        if (id == null) {
            return R.error("ID不能为空");
        }

        TccLocationTransfer entity = new TccLocationTransfer().setId(id).queryFirst();
        if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
            return R.error("已生效数据无法删除");
        }

        tccLocationTransferMapper.deleteTrue(id);

        storageMapper.deleteTccLocationTransferItemByPbid(entity.getBid());

        String loginUserId = ShiroUtils.getUserId();
        yspTaskService.flowDelete(entity.getBid(), loginUserId);
        return R.ok(EditDto.closeAndReload());
    }


    /**
     * 流转
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowPass(Long id, String loginUserId) throws Exception {
        TccLocationTransfer entity = new TccLocationTransfer().setId(id).queryFirst();
        if (entity == null) {
            return R.error("货位转移单不存在!");
        }
        try {
            String bid = entity.getBid();
            YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
            Flow f = yspTaskService.flowPass(bid, loginUserId);

            if (f.getCode() == Flow.Code.FAILED.value) {
                return R.error(f.getMsg());
            } else {
                // 若是制单流转，冻结库存
                if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                    List<TccLocationTransferItem> itemList = new TccLocationTransferItem().setPbid(bid).queryList();
                    if(itemList == null || itemList.size()<=0){
                        return R.error("该单据列表不存在,请核实后再操作!");
                    }
                    //冻结
                    for(TccLocationTransferItem item:itemList){
                        tccStockControlService.frozen(
                                item.getStockControlBeforeId(),
                                item.getTransferNum(),
                                TccStockSourceEnum.Source.TCC_LocationTransfer.value,
                                entity.getBid(),
                                item.getId()
                        );
                    }
                }
                if (f.getState() == Flow.State.FINISH.value) {
                    R r = flowFinish(entity);
                    if (r.getCode() == 1) {
                        return R.error(r.getMsg());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return R.ok();
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {
        TccLocationTransfer entity = new TccLocationTransfer().setId(id).queryFirst();
        if (entity == null) {
            return R.error("货位转移单不存在!");
        }
        String bid = entity.getBid();
        R r = yspTaskService.flowRefuse(bid, reason, ShiroUtils.getUserId());
        YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

        if (r.getCode() == R.Code.SUCCESS.value) {
            // 若退回到制单状态，则解冻库存
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                List<TccLocationTransferItem> itemList = new TccLocationTransferItem().setPbid(bid).queryList();
                if(itemList == null || itemList.size()<=0){
                    throw new IllegalArgumentException("该单据列表不存在,请核实后再操作!");
                }
                //解冻
                for(TccLocationTransferItem item:itemList){
                    tccStockControlService.thaw(
                            item.getStockControlBeforeId(),
                            item.getTransferNum(),
                            TccStockSourceEnum.Source.TCC_LocationTransfer.value,
                            item.getPbid(),
                            item.getId()
                    );
                }
            }
        }
        return r;
    }

    //流转驳回
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowInit(Long id, String reason,String loginUserId) throws Exception{
        TccLocationTransfer entity = new TccLocationTransfer().setId(id).queryFirst();
        if (entity == null) {
            return R.error("货位转移单不存在!");
        }
        String bid = entity.getBid();
        R r = yspTaskService.flowInit(bid, reason, ShiroUtils.getUserId());
        YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
        if (r.getCode() == R.Code.SUCCESS.value) {
            // 若退回到制单状态，则解冻库存
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                List<TccLocationTransferItem> itemList = new TccLocationTransferItem().setPbid(bid).queryList();
                if(itemList == null || itemList.size()<=0){
                    throw new IllegalArgumentException("该单据列表不存在,请核实后再操作!");
                }
                //解冻
                for(TccLocationTransferItem item:itemList){
                    tccStockControlService.thaw(
                            item.getStockControlBeforeId(),
                            item.getTransferNum(),
                            TccStockSourceEnum.Source.TCC_LocationTransfer.value,
                            item.getPbid(),
                            item.getId()
                    );
                }
            }
        }
        return r;
    }


    /**
     * 流转结束
     */
    public R flowFinish(TccLocationTransfer entity) throws Exception {
        try {
            YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
            if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
                return R.error("流程状态有误");
            }
            Date theDate = new Date();
            entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
            entity.setUpdateTime(theDate);

            List<TccLocationTransferItem> tccLocationTransferItems = new TccLocationTransferItem().setPbid(entity.getBid()).queryList();
            for (TccLocationTransferItem tccLocationTransferItem : tccLocationTransferItems){
                //解冻
                tccStockControlService.thaw(
                        tccLocationTransferItem.getStockControlBeforeId(),
                        tccLocationTransferItem.getTransferNum(),//数量
                        TccStockSourceEnum.Source.TCC_LocationTransfer.value,
                        entity.getBid(),
                        entity.getId()
                );
                //出库
                String remark = "货位转移单单号：" + entity.getBid();
                Integer numOut = tccLocationTransferItem.getTransferNum();
                Integer sourceTypeOut = TccStockSourceEnum.Source.TCC_LocationTransfer.value;
                tccStockControlService.outWithRunning(tccLocationTransferItem.getStockControlBeforeId(), remark + ",出库", numOut, entity.getBid(),sourceTypeOut,entity.getId());

                Long stockControlId = tccLocationTransferItem.getStockControlBeforeId();
                TccStockControl tccStockControl = new TccStockControl().setId(stockControlId).queryFirst();

                Integer sourceType = TccStockSourceEnum.Source.TCC_LocationTransfer.value;
                String assembleBid = tccLocationTransferItem.getAssembleBid();
                R res =  tccStockControlService.inWithRunning(tccStockControl.getRkBid(), tccLocationTransferItem.getChw(), tccStockControl.getProductName(),
                        tccLocationTransferItem.getTransferNum(), tccStockControl.getProductCode(), tccLocationTransferItem.getTransferNum(),
                        tccStockControl.getPurchasePrice(), tccStockControl.getPurchasePrice().multiply(new BigDecimal(tccLocationTransferItem.getTransferNum())),
                        null, null,
                        tccStockControl.getVgsbm(),tccStockControl.getDrksj(), tccStockControl.getIsParent(), entity.getBid(), sourceType,
                        remark + ",入库", tccStockControl.getCompanyVid(), assembleBid,entity.getId());
                if (res.getCode() != 0) {
                    throw new RuntimeException(res.getMsg());
                }
                tccLocationTransferItem.setStockControlAfterId(Long.parseLong(res.get("data").toString()));
                tccLocationTransferItemMapper.update(tccLocationTransferItem);
            }
            tccLocationTransferMapper.update(entity);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return R.ok();
    }
}
